package com.rech.utils;

import android.annotation.SuppressLint;
import android.app.ActivityManager;
import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.media.AudioManager;
import android.media.MediaPlayer;
import android.media.SoundPool;
import android.net.ConnectivityManager;
import android.net.NetworkCapabilities;
import android.net.NetworkInfo;
import android.os.Environment;
import android.util.Base64;
import android.util.DisplayMetrics;
import android.util.Log;
import android.view.Window;
import android.view.WindowManager;
import android.widget.Toast;


import com.example.x6.gpio_3288demo.LightUtils;
import com.rech.xbexpress3.R;

import java.io.BufferedReader;
import java.io.ByteArrayOutputStream;
import java.io.DataOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.lang.reflect.Field;
import java.net.InetSocketAddress;
import java.net.MalformedURLException;
import java.net.Socket;
import java.net.URL;
import java.nio.charset.Charset;
import java.text.ParsePosition;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import static android.support.constraint.Constraints.TAG;
import static io.reactivex.schedulers.Schedulers.start;

public class OtherUtil {
    public static String verStr = "V0.0.1";
    public static Boolean submitEnable = false;
    public static Map<String,String> keyValue=new HashMap<String,String>();
    private static Boolean faceCapture = false; //是否捕捉到活体 等待确认发送验证
    private static Boolean faceEnable = false;
    private static MediaPlayer player = null;
    private static String token;
    private static Context ctx ;
    private static OtherUtil singletonOtherUtil = new OtherUtil();
    //将构造器设置为private禁止通过new进行实例化
    private OtherUtil() {

    }
    public static OtherUtil getInstance() {
        return singletonOtherUtil;
    }


    public static Boolean setMainContext(Context argctx){
        ctx = argctx;
        return true;
    }
    public static Context getMainContext(){
        return ctx;
    }
    public static Boolean isFaceCapture(){
        return faceCapture;
    }
    public static Boolean FaceCaptureEnable(){
        faceCapture = true;
        return true;
    }
    public static Boolean FaceCaptureDisable(){
        faceCapture = false;
        return true;
    }
    public static int differentDaysByMillisecond(Date date1, Date date2)
    {
        int days = (int) ((date2.getTime() - date1.getTime()) / (1000*3600*24));
        return days;
    }

    public static Date strToDate(String strDate) {
        SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd");
        ParsePosition pos = new ParsePosition(0);
        Date strtodate = formatter.parse(strDate, pos);
        return strtodate;
    }
    public static String DateToStr(Date dateDate) {

        SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd");
        String dateString = formatter.format(dateDate);
        return dateString;
    }
    public static Boolean isFaceEnable(){
        return faceEnable;
    }
    public static Boolean FaceEnableEnable(){
        faceEnable = true;
        return true;
    }
    public static Boolean FaceEnableDisable(){
        faceEnable = false;
        return true;
    }

    public static Boolean isSubmitEnable(){
        return submitEnable;
    }
    public static Boolean SubmitEnable(){
        submitEnable = true;
        return true;
    }
    public static Boolean SubmitDisable(){
        submitEnable = false;
        return true;
    }
    public static boolean isKeyboardActive(Window win){

        if(win.getAttributes().softInputMode == WindowManager.LayoutParams.SOFT_INPUT_STATE_VISIBLE){
            Toast.makeText(getMainContext(), "显示", Toast.LENGTH_SHORT).show();
            return true;
        }else {
            Toast.makeText(getMainContext(), "没显示", Toast.LENGTH_SHORT).show();
            return false;

        }

    }
    public static void StartupNotify(Context ctx){//请及时存好包裹关上箱门
        try{
            Intent intent = new Intent();
            intent.setClassName("com.xbexpress.expressnotify", "com.xbexpress.expressnotify.MainActivity");
            ctx.startActivity(intent);
        }catch(Exception e){
            e.printStackTrace();
        }
    }
    public static int getResId(String variableName, Class<?> c) {
        try {
            Field idField = c.getDeclaredField(variableName);
            return idField.getInt(idField);
        } catch (Exception e) {
            e.printStackTrace();
            return -1;
        }
    }
    public static String getUniqueToken(){
        token = String.valueOf(System.currentTimeMillis());
        return token;
    }
    public static boolean isUniqueToken(String value){
        try {
            return token.equals(value);
        }catch (Exception e){
            return false;
        }
    }
    public static void OpenVoice1(final Context ctx){//欢迎使用箱宝快递柜自助
        try {
            Runnable task = new Runnable() {
                @Override
                public void run() { // 覆盖重写抽象方法
                    player = MediaPlayer.create(ctx,R.raw.v1);
                    player.start();
                }
            };
            new Thread(task).start(); // 启动线程

        } catch (Exception e) {
            e.printStackTrace();
        }

    }
    public static void OpenVoice2(final Context ctx){//请及时存好包裹关上箱门
        try {
            Runnable task = new Runnable() {
                @Override
                public void run() { // 覆盖重写抽象方法
                    player = MediaPlayer.create(ctx,R.raw.v2);
                    player.start();
                }
            };
            new Thread(task).start(); // 启动线程

        } catch (Exception e) {
            e.printStackTrace();
        }
    }
    public static void OpenVoice3(final Context ctx){//请扫描身份证，面对屏幕正前方

        try {
            Runnable task = new Runnable() {
                @Override
                public void run() { // 覆盖重写抽象方法
                    try{
                        Thread.sleep(1000);
                        player = MediaPlayer.create(ctx,R.raw.v3);
                        player.start();
                    }catch (Exception e){

                    }

                }
            };
            new Thread(task).start(); // 启动线程

        } catch (Exception e) {
            e.printStackTrace();
        }
    }
    public static void OpenVoice4(final Context ctx){//请关好箱门
        try {
            Runnable task = new Runnable() {
                @Override
                public void run() { // 覆盖重写抽象方法
                    player = MediaPlayer.create(ctx,R.raw.v4);
                    player.start();
                }
            };
            new Thread(task).start(); // 启动线程

        } catch (Exception e) {
            e.printStackTrace();
        }
    }
    public static void OpenVoice5(final Context ctx){//箱门已打开，请及时取走包裹，关好箱门
        try {
            Runnable task = new Runnable() {
                @Override
                public void run() { // 覆盖重写抽象方法
                    player = MediaPlayer.create(ctx,R.raw.v5);
                    player.start();
                }
            };
            new Thread(task).start(); // 启动线程

        } catch (Exception e) {
            e.printStackTrace();
        }
    }
    public static void OpenVoice6(final Context ctx){//验证成功请输入手机号码
        try {
            Runnable task = new Runnable() {
                @Override
                public void run() { // 覆盖重写抽象方法
                    player = MediaPlayer.create(ctx,R.raw.v6);
                    player.start();
                }
            };
            new Thread(task).start(); // 启动线程

        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    public static void OpenVoice7(final Context ctx){//柜门已开，请及时操作
        try {
            Runnable task = new Runnable() {
                @Override
                public void run() { // 覆盖重写抽象方法
                    player = MediaPlayer.create(ctx,R.raw.v7);
                    player.start();
                }
            };
            new Thread(task).start(); // 启动线程

        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    public static void OpenVoice8(final Context ctx){//请点击通知快递员揽收按钮，完成寄件
        try {
            Runnable task = new Runnable() {
                @Override
                public void run() { // 覆盖重写抽象方法
                    player = MediaPlayer.create(ctx,R.raw.v8);
                    player.start();
                }
            };
            new Thread(task).start(); // 启动线程

        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    public static void OpenVoice9(final Context ctx){//请面对屏幕正前方

        try {
            Runnable task = new Runnable() {
                @Override
                public void run() { // 覆盖重写抽象方法
                    try{
                        Thread.sleep(1000);
                        player = MediaPlayer.create(ctx,R.raw.v9);
                        player.start();
                    }catch (Exception e){

                    }

                }
            };
            new Thread(task).start(); // 启动线程

        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    public static boolean isExistUID(Context ctx) {
        try {
            String uid = getUID(ctx);
            if(uid.length() == 0){
                return false;
            }
            return true;

        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
    }

    public static void initOrientation() {

    }

    public String createUID(Context ctx){
        String uid= String.valueOf(System.currentTimeMillis());
        setUID(ctx,uid);
        return uid;
    }
    public static String getUID(Context ctx){
        String line = null;
        try {
            String rootPath = Environment.getExternalStorageDirectory().toString();
            File file = new File(rootPath + "/uid.txt");
            FileInputStream fileInputStream = new FileInputStream(file);

            BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(fileInputStream));



            while ((line = bufferedReader.readLine()) != null) {
                return line;
            }

            fileInputStream.close();

        } catch (Exception e) {
            e.printStackTrace();
            line = "";
        }
        return line;
    }
    public static boolean setUID(Context ctx,String uuid){
        try {
            Log.d(TAG,"setUID:"+uuid);
            String rootPath = Environment.getExternalStorageDirectory().toString();
            File file = new File(rootPath+"/uid.txt");
            FileOutputStream fileOutputStream = new FileOutputStream(file);
            fileOutputStream.write(uuid.getBytes());

            fileOutputStream.close();
            return true;

        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
    }

    public static String getOrientation(Context ctx){
        String line = null;
        try {
            String rootPath = Environment.getExternalStorageDirectory().toString();
            File file = new File(rootPath + "/orientation.txt");
            FileInputStream fileInputStream = new FileInputStream(file);

            BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(fileInputStream));



            while ((line = bufferedReader.readLine()) != null) {
                return line;
            }

            fileInputStream.close();

        } catch (Exception e) {
            e.printStackTrace();
            line = "";
        }
        return line;
    }

    public static boolean setOrientation(Context ctx,String orientation){
        try {
            String rootPath = Environment.getExternalStorageDirectory().toString();
            File file = new File(rootPath+"/orientation.txt");
            FileOutputStream fileOutputStream = new FileOutputStream(file);
            fileOutputStream.write(orientation.getBytes());

            fileOutputStream.close();
            return true;

        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
    }

    public static void restartApplication(Context ctx) {
        Intent intent = new Intent();
        intent.setClassName("com.rech.xbexpress3", "com.rech.xbexpress3.FullscreenActivity");
        ctx.startActivity(intent);
        android.os.Process.killProcess(android.os.Process.myPid());

    }

    public String getAppVersion() {

        return verStr;
    }
    public String getAppSerial(Context ctx) {

        if(isExistUID(ctx)){
            return getUID(ctx);
        }else{
            createUID(ctx);
            return getUID(ctx);
        }
    }
    public static boolean silentInstall(String apkPath) {
        boolean result = false;
        DataOutputStream dataOutputStream = null;
        BufferedReader errorStream = null;
        BufferedReader successStream = null;
        Process process = null;
        try {
            // 申请 su 权限
            process = Runtime.getRuntime().exec("su");
            dataOutputStream = new DataOutputStream(process.getOutputStream());
            // 执行 pm install 命令
            String command = "pm install -r " + apkPath + "\n";
            dataOutputStream.write(command.getBytes(Charset.forName("UTF-8")));
            dataOutputStream.writeBytes("exit\n");
            dataOutputStream.flush();
            process.waitFor();
            errorStream = new BufferedReader(new InputStreamReader(process.getErrorStream()));
            StringBuilder errorMsg = new StringBuilder();
            String line;
            while ((line = errorStream.readLine()) != null) {
                errorMsg.append(line);
            }
            //log.debug("silent install error message:{}", errorMsg);
            StringBuilder successMsg = new StringBuilder();
            successStream = new BufferedReader(new InputStreamReader(process.getInputStream()));
            // 读取命令执行结果
            while ((line = successStream.readLine()) != null) {
                successMsg.append(line);
            }
            //log.debug("silent install success message:{}", successMsg);
            // 如果执行结果中包含 Failure 字样就认为是操作失败，否则就认为安装成功
            if (!(errorMsg.toString().contains("Failure") || successMsg.toString().contains("Failure"))) {
                result = true;
            }
        } catch (Exception e) {
            //log.error(e);
        } finally {
            try {
                if (process != null) {
                    process.destroy();
                }
                if (dataOutputStream != null) {
                    dataOutputStream.close();
                }
                if (errorStream != null) {
                    errorStream.close();
                }
                if (successStream != null) {
                    successStream.close();
                }
            } catch (Exception e) {
                // ignored
            }
        }
        return result;
    }

    public static boolean isRoot() {
        return new File("/system/bin/su").exists() || new File("/system/xbin/su").exists();
    }

    public static String bitmapToBase64(Bitmap bitmap) {

        String result = null;
        ByteArrayOutputStream baos = null;
        try {
            if (bitmap != null) {
                baos = new ByteArrayOutputStream();
                bitmap.compress(Bitmap.CompressFormat.JPEG, 100, baos);

                baos.flush();
                baos.close();

                byte[] bitmapBytes = baos.toByteArray();
                result = Base64.encodeToString(bitmapBytes, Base64.DEFAULT);
            }
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            try {
                if (baos != null) {
                    baos.flush();
                    baos.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        return result;
    }

    /**
     * base64转为bitmap
     * @param base64Data
     * @return
     */
    public static Bitmap base64ToBitmap(String base64Data) {
        byte[] bytes = Base64.decode(base64Data, Base64.DEFAULT);
        return BitmapFactory.decodeByteArray(bytes, 0, bytes.length);
    }
    public static String getValue(String key){
        String value = "";
        if(keyValue.containsKey(key)){
            value = keyValue.get(key);
        }
        return value;
    }
    public static void setValue(String key,String value){
        keyValue.put(key,value);
    }

    public static boolean isServiceRunning(Context context){
        String MY_PKG_NAME = "ExpressNotify";
        boolean isAppRunning = false;
        ActivityManager am = (ActivityManager)context.getSystemService(Context.ACTIVITY_SERVICE);
        List<ActivityManager.RunningTaskInfo> list = am.getRunningTasks(100);
        for (ActivityManager.RunningTaskInfo info : list) {
            if (info.topActivity.getPackageName().equals(MY_PKG_NAME) && info.baseActivity.getPackageName().equals(MY_PKG_NAME)) {
                isAppRunning = true;
                //find it, break
                break;
            }
        }
        return isAppRunning;
    }


    private static boolean isAppInstalled(Context context,String packagename)
    {
        PackageInfo packageInfo;
        try {
            packageInfo = context.getPackageManager().getPackageInfo(packagename, 0);
        }catch (PackageManager.NameNotFoundException e) {
            packageInfo = null;
            e.printStackTrace();
        }
        if(packageInfo ==null){
            //System.out.println("没有安装");
            return false;
        }else{
            //System.out.println("已经安装");
            return true;
        }
    }
    public static  boolean isServiceStarted(Context context,String PackageName) {
        //<uses-permission android:name="android.permission.GET_TASKS"/>
        //https://crazier9527.iteye.com/blog/1476134
        boolean isStarted =false;
        try {
            ActivityManager activityManager = (ActivityManager) context
                    .getSystemService(Context.ACTIVITY_SERVICE);
            List<ActivityManager.RunningAppProcessInfo> infos = activityManager
                    .getRunningAppProcesses();

            for (ActivityManager.RunningAppProcessInfo info : infos)
            {
                String name = info.processName;//com.xbexpress.expressnotify
                if(PackageName.equals(name)){
                    isStarted = true;
                }


            }

        }
        catch(SecurityException e) {
            e.printStackTrace();
        }
        return isStarted;
    }
    public static boolean isBackground(Context context) {
        ActivityManager activityManager = (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE);
        List<ActivityManager.RunningAppProcessInfo> appProcesses = activityManager.getRunningAppProcesses();
        for (ActivityManager.RunningAppProcessInfo appProcess : appProcesses) {
            if (appProcess.processName.equals(context.getPackageName())) {
                if (appProcess.importance == ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND) {
                    Log.i("后台", appProcess.processName);
                    return true;
                } else {
                    Log.i("前台", appProcess.processName);
                    return false;
                }
            }
        }
        return false;
    }
    private static void bindPort(String host,int port)throws Exception{
        //创建一个socket对象
        Socket s = new Socket();
        //对指定端口进行绑定，如果绑定成功则未被占用
        s.bind(new InetSocketAddress(host,port));
        s.close();
    }
    public static boolean isPortAvailable(int port){
        try{
            //调用bindport函数对本机指定端口进行验证
            bindPort("127.0.0.1",port);
            //bindPort(InetAddress.getLocalHost().getHostAddress(),port);
            return true;
        }catch (Exception e){
            return false;
        }
    }

    public static String getCurrentTime(){
        Date d = new Date();
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        return sdf.format(d);
    }

    /**
     * 得到当前时间
     *
     * @return
     */
    @SuppressLint("SimpleDateFormat")
    public static String getTime() {
        SimpleDateFormat format = new SimpleDateFormat(
                "HH:mm:ss");
        Date date = new Date(System.currentTimeMillis());
        String strDate = format.format(date);
        return strDate;
    }

    static public void OpenLight(){


        try{
            LightUtils.OpenLight();
        }catch (Exception e){
            e.printStackTrace();
        }



    }
    static public void CloseLight(){
        try{
            LightUtils.CloseLight();
        }catch (Exception e){
            e.printStackTrace();
        }


    }

    /**
     * 判断网络是否连接
     *
     * @param context context
     * @return true/false
     */
    public static boolean isNetConnected(Context context) {
        ConnectivityManager connectivity = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
        if (connectivity != null) {
            NetworkInfo info = connectivity.getActiveNetworkInfo();
            if (info != null && info.isConnected()) {
                if (info.getState() == NetworkInfo.State.CONNECTED) {
                    return true;
                }
            }
        }
        return false;
    }

    /**
     * 在子线程里开启该方法，可检测当前网络是否能打开网页
     * true是可以上网，false是不能上网
     */
    public static boolean isOnline() {
        URL url;
        try {
            url = new URL("https://www.baidu.com");
            InputStream stream = url.openStream();
            return true;
        } catch (MalformedURLException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
        return false;
    }

    public static boolean netCanUse(Context context) {
        if (context != null) {
            ConnectivityManager mConnectivityManager = (ConnectivityManager) context
                    .getSystemService(Context.CONNECTIVITY_SERVICE);
            NetworkInfo mNetworkInfo = mConnectivityManager.getActiveNetworkInfo();
            if (mNetworkInfo != null) {
                if (!mNetworkInfo.isAvailable()) {
                    return false;
                }
                if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.M) {
                    NetworkCapabilities networkCapabilities = mConnectivityManager.getNetworkCapabilities(mConnectivityManager.getActiveNetwork());
                    return networkCapabilities.hasCapability(NetworkCapabilities.NET_CAPABILITY_VALIDATED);
                } else {
                    Runtime runtime = Runtime.getRuntime();
                    try {
                        Process ipProcess = runtime.exec("ping -c 3 www.baidu.com");
                        int exitValue = ipProcess.waitFor();
                        Log.i("Avalible", "Process:" + exitValue);
                        return (exitValue == 0);
                    } catch (IOException | InterruptedException e) {
                        e.printStackTrace();
                    }
                }
            }
        }
        return false;
    }

    public static boolean isMobile(String mobile) {
        String str = mobile;
        String pattern = "^(13[0-9]|15[012356789]|17[013678]|18[0-9]|14[57]|19[89]|166)[0-9]{8}";
        Pattern r = Pattern.compile(pattern);
        Matcher m = r.matcher(str);
        return m.matches();
    }

    public static int getDensityDpi(Context context){
        DisplayMetrics dm = context.getResources().getDisplayMetrics();
        return dm.densityDpi;
    }

    public static int dp2px(float dpValue) {
        final float scale = getMainContext().getResources().getDisplayMetrics().density;
        return (int) (dpValue * scale + 0.5f);
    }

    /**
     * 获取当前应用的版本号
     *
     * @param context
     * @return
     * @throws Exception
     */
    public static String getVersion(Context context) throws Exception {
        // 获取packagemanager的实例
        PackageManager packageManager = context.getPackageManager();
        // getPackageName()是你当前类的包名，0代表是获取版本信息
        PackageInfo packInfo = packageManager.getPackageInfo(context.getPackageName(), 0);
        String version = packInfo.versionName;
        return version;
    }
}
